/*
 * PropertyInfo.java
 *
 * $Id: PropertyInfo.java,v 1.1 2008-03-18 12:58:46 mario Exp $
 */
package org.ceteca.explica.core.traceability.tree;

import java.math.BigDecimal;
import java.util.Hashtable;

import org.ceteca.explica.core.traceability.InterfaceTraceabilityTree;
import org.ceteca.explica.core.util.DateTime;

/**
 * ValueObject with the data of a Property item.
 * <br/>
 * Responsibilities:
 * <ul>
 *  <li>Store the property data.</li>
 * </ul>
 * <br/>
 * @author Mario García García <mario@imagos.es>
 * Copyright (c) 2007 Fundación Centro Tecnolóxico da Carne
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * <br/>
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * <br/>
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
public class PropertyInfo {
	/** 
	 * Constant definition with the property type NONE. 
	 * It's the default value to point out that no property type 
	 * has been assigned yet.
	 */
	public static final int PROPERTY_TYPE_NONE = 0;
	/** 
	 * Constant definition with the property type NUMBER. 
	 * It's the value for properties of any type of numeric value, such
	 * as Integers, Floats, Decimals, Doubles, etc.
	 */
	public static final int PROPERTY_TYPE_NUMBER = 1;
	/** 
	 * Constant definition with the property type STRING. 
	 * It's the value for properties of any type of alphanumeric string 
	 * value.
	 */
	public static final int PROPERTY_TYPE_STRING = 2;
	/** 
	 * Constant definition with the property type DATE. 
	 * It's the value for properties of date/time values in any format.
	 */
	public static final int PROPERTY_TYPE_DATE = 3;
	/** 
	 * Constant definition with the property type BOOLEAN. 
	 * It's the value for properties with a True/False, On/Off value.
	 */
	public static final int PROPERTY_TYPE_BOOLEAN = 4;
	/** 
	 * Constant definition with the property type OBJECT. 
	 * It's the value for properties of any other type of value different
	 * from the ones described above, as for example, BLOBS, IMAGES, etc.
	 */
	public static final int PROPERTY_TYPE_OBJECT = 5;
	
	/** 
	 * Constant definition with the text showed to the user for
	 * the property type NONE.
	 * @see org.ceteca.explica.core.traceability.tree.PropertyInfo#PROPERTY_TYPE_NONE
	 */
	public static final String CONST_PROPERTY_TYPE_NONE = "-----";
	/** 
	 * Constant definition with the text showed to the user for
	 * the property type NUMBER.
	 * @see org.ceteca.explica.core.traceability.tree.PropertyInfo#PROPERTY_TYPE_NUMBER
	 */
	public static final String CONST_PROPERTY_TYPE_NUMBER = "NUMBER";
	/** 
	 * Constant definition with the text showed to the user for
	 * the property type STRING.
	 * @see org.ceteca.explica.core.traceability.tree.PropertyInfo#PROPERTY_TYPE_STRING
	 */
	public static final String CONST_PROPERTY_TYPE_STRING = "STRING";
	/** 
	 * Constant definition with the text showed to the user for
	 * the property type DATE.
	 * @see org.ceteca.explica.core.traceability.tree.PropertyInfo#PROPERTY_TYPE_DATE
	 */
	public static final String CONST_PROPERTY_TYPE_DATE = "DATE";
	/** 
	 * Constant definition with the text showed to the user for
	 * the property type BOOLEAN.
	 * @see org.ceteca.explica.core.traceability.tree.PropertyInfo#PROPERTY_TYPE_BOOLEAN
	 */
	public static final String CONST_PROPERTY_TYPE_BOOLEAN = "BOOLEAN";
	/** 
	 * Constant definition with the text showed to the user for
	 * the property type OBJECT.
	 * @see org.ceteca.explica.core.traceability.tree.PropertyInfo#PROPERTY_TYPE_OBJECT
	 */
	public static final String CONST_PROPERTY_TYPE_OBJECT = "OBJECT";
	
	/** Hashtable that links any property type with its corresponding
	 * label showed to the user.
	 */
	public static final Hashtable propertyTypes = new Hashtable();
	// A static initializer that fills the hashtable of property types
	static {
		propertyTypes.put(PROPERTY_TYPE_NONE, CONST_PROPERTY_TYPE_NONE);
		propertyTypes.put(PROPERTY_TYPE_NUMBER, CONST_PROPERTY_TYPE_NUMBER);
		propertyTypes.put(PROPERTY_TYPE_STRING, CONST_PROPERTY_TYPE_STRING);
		propertyTypes.put(PROPERTY_TYPE_DATE, CONST_PROPERTY_TYPE_DATE);
		propertyTypes.put(PROPERTY_TYPE_BOOLEAN, CONST_PROPERTY_TYPE_BOOLEAN);
		propertyTypes.put(PROPERTY_TYPE_OBJECT, CONST_PROPERTY_TYPE_OBJECT);
	}
	
	/** Property code */
	private String cod;
	/** Property value. It will store the value of any kind of type. It's
	 * later when the property type has been setted up, that the property's
	 * value will be stored with its corresponding format, i.e. as an Integer,
	 * as a String, as a Date, as a Boolean, etc. */
	private Object val;
	/** Property type */
	private int type;
	/** Property description */
	private String description;
	/** Property pattern format. Plus to the property type, in most cases
	 * the user will be allowed to specify with more detail the format pattern
	 * that the values will follow. For example with the numeric properties,
	 * user can specify the number of integer digits and the number of decimal
	 * digits, with dates he can speficy the date format, etc. */
	private String pattern;

	/**
	 * Default PropertyInfo constructor.
	 */
	public PropertyInfo() {
		this.setCod(null);
		this.setType(PROPERTY_TYPE_NONE);
		this.setVal(null);
		this.setDescription(null);
		this.setPattern(null);
	}
	
	/**
	 * PropertyInfo constructor that initializes the property values.
	 * @param cod String, property code.
	 * @param val String, property value in String format.
	 * @param type String, property type.
	 * @param description String, property description.
	 * @param pattern String, property format pattern.
	 */
	public PropertyInfo(String cod, String val, String type, String description, String pattern) {
		this.setCod(cod);
		try {
			this.setType(Integer.parseInt(type));
		}
		catch (Exception ex) {
			this.setType(PROPERTY_TYPE_NONE);
		}
		
		switch (this.getType()) {
			case PROPERTY_TYPE_NUMBER:
				this.setVal(new BigDecimal(val));
				break;
			case PROPERTY_TYPE_STRING:
				this.setVal(val);
				break;
			case PROPERTY_TYPE_DATE:
				if (pattern != null && pattern.length() > 0)
					this.setVal(new DateTime(val, pattern));
				else
					this.setVal(new DateTime(val, InterfaceTraceabilityTree.CONST_SHORT_DATE_PATTERN));
				break;
			case PROPERTY_TYPE_BOOLEAN:
				this.setVal(new Boolean(Boolean.parseBoolean(val)));
				break;
			case PROPERTY_TYPE_OBJECT:
				this.setVal(val.getBytes());
				break;
			default:
				this.setVal(null);
		}
		this.setDescription(description);
		this.setPattern(pattern);
	}

	/**
	 * Gets the property code.
	 * @return String, property code.
	 */
	public String getCod() {
		return cod;
	}
	/**
	 * Sets up the property code.
	 * @param cod String, a property code.
	 */
	public void setCod(String cod) {
		this.cod = cod;
	}
	/**
	 * Gets the property description.
	 * @return String, property description.
	 */
	public String getDescription() {
		return description;
	}
	/**
	 * Sets up the property description.
	 * @param description String, a description.
	 */
	public void setDescription(String description) {
		this.description = description;
	}
	/**
	 * Gets the property type.
	 * @return int, property type.
	 * @see org.ceteca.explica.core.traceability.tree.PropertyInfo#PROPERTY_TYPE_NONE
	 * @see org.ceteca.explica.core.traceability.tree.PropertyInfo#PROPERTY_TYPE_NUMBER
	 * @see org.ceteca.explica.core.traceability.tree.PropertyInfo#PROPERTY_TYPE_STRING
	 * @see org.ceteca.explica.core.traceability.tree.PropertyInfo#PROPERTY_TYPE_DATE
	 * @see org.ceteca.explica.core.traceability.tree.PropertyInfo#PROPERTY_TYPE_BOOLEAN
	 * @see org.ceteca.explica.core.traceability.tree.PropertyInfo#PROPERTY_TYPE_OBJECT
	 */
	public int getType() {
		return type;
	}
	/**
	 * Sets up the property type.
	 * @param type int, a property type.
	 * @see org.ceteca.explica.core.traceability.tree.PropertyInfo#PROPERTY_TYPE_NONE
	 * @see org.ceteca.explica.core.traceability.tree.PropertyInfo#PROPERTY_TYPE_NUMBER
	 * @see org.ceteca.explica.core.traceability.tree.PropertyInfo#PROPERTY_TYPE_STRING
	 * @see org.ceteca.explica.core.traceability.tree.PropertyInfo#PROPERTY_TYPE_DATE
	 * @see org.ceteca.explica.core.traceability.tree.PropertyInfo#PROPERTY_TYPE_BOOLEAN
	 * @see org.ceteca.explica.core.traceability.tree.PropertyInfo#PROPERTY_TYPE_OBJECT
	 */
	public void setType(int type) {
		this.type = type;
	}
	/**
	 * Gets the property value.
	 * @return Object, property value.
	 */
	public Object getVal() {
		return val;
	}
	/**
	 * Sets up the property code.
	 * @param val Object, a value.
	 */
	public void setVal(Object val) {
		this.val = val;
	}
	/**
	 * Gets the property format pattern.
	 * @return String, property format pattern.
	 */
	public String getPattern() {
		return pattern;
	}
	/**
	 * Sets up the property format pattern.
	 * @param pattern String, a format pattern.
	 */
	public void setPattern(String pattern) {
		this.pattern = pattern;
	}
	
	/**
	 * Converts the property info to a formatted String.
	 * @return String, formatted String with the property's data.
	 */
	public String toString() {
		StringBuffer result = new StringBuffer();
		result.append(this.cod);
		result.append(" = ");
		result.append(this.val);
		result.append("   (");
		result.append(this.type);
		result.append(")   : ");
		result.append(this.description);
		
		return result.toString();
	}
	
	/**
	 * Updates the property data.
	 * @param info PropertyInfo, new property data.
	 */
	public void update(PropertyInfo info) {
		this.setCod(info.getCod());
		this.setVal(info.getVal());
		this.setDescription(info.getDescription());
		this.setType(info.getType());
		this.setPattern(info.getPattern());
	}
	
	/**
	 * Returns tag Id assigned to CVS source file.
	 */
	public static String getRevision() {
		return "$Id: PropertyInfo.java,v 1.1 2008-03-18 12:58:46 mario Exp $";
	}
}
